﻿#pragma once

#include "BaseShader.h"
/// <summary>
/// 色阶调节Shader
/// ps：色阶（Levels） 调整通过控制阴影（暗部）、中间调（灰阶）和高光（亮部）的分布，来改变图像的对比度和色调范围
/// shadow	黑场阈值。低于此值的像素会被压暗为纯黑（0.0），值越大，暗部区域越广。
/// highlight	白场阈值。高于此值的像素会被提亮为纯白（1.0），值越小，高光区域越广。
/// midtone	中间调 gamma 值。控制灰阶亮度：
/// - 大于 1.0：中间调变暗（对比度增强）
/// - 小于 1.0：中间调变亮（对比度降低）
/// - 等于 1.0：中间调不变。
/// </summary>
class CtrlLShader : public BaseShader
{
	Q_OBJECT

public:
	/*static CtrlLShader* Get()
	{
		static CtrlLShader cls;
		return &cls;
	}*/
	CtrlLShader(QObject* parent = nullptr);
	~CtrlLShader();
private:
	
	//顶点着色器代码
	QString vertexSource = R"(
	attribute vec4 vertexIn;
	attribute vec2 textureIn;
	varying vec2 textureOut;
	void main(void)
	{
		gl_Position = vertexIn;
		textureOut = textureIn;
	}
	)";

	//片元着色器代码
	QString fragmentSource = R"(
	varying vec2 textureOut;
	uniform sampler2D tex_y;
	uniform sampler2D tex_u;
	uniform sampler2D tex_v;
	// 色阶参数（范围0.0~1.0）
	uniform float shadow;    // 黑场阈值（低于此值的像素变为纯黑）
	uniform float midtone;   // 灰场gamma值（控制中间调亮度）
	uniform float highlight; // 白场阈值（高于此值的像素变为纯白）
	void main(void)
	{
		vec3 yuv;
		vec3 rgb;
		yuv.x = texture2D(tex_y, textureOut).r;
		yuv.y = texture2D(tex_u, textureOut).r - 0.5;
		yuv.z = texture2D(tex_v, textureOut).r - 0.5;
		rgb = mat3(1.0, 1.0, 1.0,
			0.0, -0.39465, 2.03211,
			1.13983, -0.58060, 0.0) * yuv;

		// 色阶调整核心逻辑
		// 1. 裁剪黑场（低于shadow的像素设为0）
		rgb = max(rgb - shadow, 0.0);
    
		// 2. 压缩范围到[0, highlight - shadow]，并归一化到[0,1]
		float range = max(highlight - shadow, 0.0001); // 避免除以0
		rgb = rgb / range;
    
		// 3. 调整中间调（gamma校正）
		rgb = pow(rgb, vec3(1.0 / midtone));
    
		// 4. 裁剪白场（高于1.0的像素设为1）
		rgb = clamp(rgb, 0.0, 1.0);
		gl_FragColor = vec4(rgb,1.0);
	}
	)";
};
